#pragma once
#include "Epoll.h"
#include "Channel.h"
#include <memory>
#include<queue>
#include<mutex>
#include<sys/eventfd.h>
#include<sys/timerfd.h>
#include<map>
#include "Connection.h"
#include<atomic>

class Epoll;
class Channel;
class Connection;

class EventLoop
{
private:
    // Epoll *ep_;
    std::unique_ptr<Epoll> ep_;
    std::function<void(EventLoop *)> epolltimeoutcallback_;
    pid_t threadid_;    //事件循环所在线程的id
    
    std::queue<std::function<void()>> taskqueue_;
    std::mutex mutex_;

    int wakeupfd_;

    std::unique_ptr<Channel> wakechannel_;
    
    int timetvl_; // 闹钟时间间隔
    int timeout_; // 超时时间

    int timerfd_;
    std::unique_ptr<Channel> timerchannel_;

    bool ismainloop_;
    std::mutex mmutex_;
    std::map<int,std::shared_ptr<Connection>> conns_;  //存放运行该事件循环上全部的Connection对象

    std::function<void(int)> removeconncallback_;

    std::atomic_bool stop_;



public:
    EventLoop(bool ismainloop,int timetvl=30,int timeout=80);
    ~EventLoop();

    void run();
    void stop();

    Epoll* ep();


    void updatechannel(Channel *ch);

    void removechannel(Channel *ch);  //从红黑树上删除channel

    void setepolltimeoutcallback(std::function<void(EventLoop *)>);

    bool isinloopthread(); //判断当前线程是否为事件循环线程

    void queueinloop(std::function<void()> f);

    void wakeup();

    void haddlewakeup();

    void handletimer();

    void newconnection(std::shared_ptr<Connection> conn);

    void setremoveconncallback(std::function<void(int)> f);

};
